﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Helpers {
    /// <summary>
    /// 常用加密方法类
    /// </summary>
    public class SecurityHelper {

        #region Private

        // bytes 转换成 16 进制
        private static string BytesToHex(byte[] bytes) {
            if (bytes.Length == 0) return string.Empty;
            StringBuilder sb = new StringBuilder();
            foreach (byte b in bytes) {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString().ToLower();
        }
        // 16 进制转换成 bytes
        private static byte[] HexToByte(string str) {
            if (string.IsNullOrEmpty(str)) return null;
            int bytesLength = str.Length / 2;
            byte[] bytes = new byte[bytesLength];
            for (int i = 0; i < bytesLength; i++) {
                bytes[i] = (byte)Convert.ToInt32(str.Substring(i * 2, 2), 16);
            }
            return bytes;
        }

        #endregion

        /// <summary>
        /// MD5 加密（不可逆）
        /// </summary>
        /// <param name="str">被加密字符</param>
        /// <returns>加密后的字符串</returns>
        public static string MD5Hash(string str) {
            MD5 helper = MD5.Create();
            byte[] bytes = helper.ComputeHash(Encoding.Default.GetBytes(str));
            return BytesToHex(bytes);
        }
        /// <summary>
        /// SHA1 加密（不可逆）
        /// </summary>
        /// <param name="str">被加密字符</param>
        /// <returns>加密后的字符串</returns>
        public static string SHA1Hash(string str) {
            SHA1 helper = new SHA1Managed();
            byte[] bytes = helper.ComputeHash(Encoding.Default.GetBytes(str));
            return BytesToHex(bytes);
        }
        /// <summary>
        /// SHA256 加密（不可逆）
        /// </summary>
        /// <param name="str">被加密字符</param>
        /// <returns>加密后的字符串</returns>
        public static string SHA256Hash(string str) {
            SHA256 helper = new SHA256Managed();
            byte[] bytes = helper.ComputeHash(Encoding.Default.GetBytes(str));
            return BytesToHex(bytes);
        }
        /// <summary>
        /// DES 加密
        /// </summary>
        /// <param name="str">被加密字符</param>
        /// <returns>加密后的字符串</returns>
        public static string DESEncrypt(string str) {
            return DESEncrypt(str, "Match_Zhou_2009_02_11");
        }
        /// <summary>
        /// DES 加密
        /// </summary>
        /// <param name="str">被加密字符</param>
        /// <param name="key">加密 key</param>
        /// <returns>加密后的字符串</returns>
        public static string DESEncrypt(string str, string key) {
            DES helper = DES.Create();
            byte[] keyBytes = ASCIIEncoding.ASCII.GetBytes(MD5Hash(key).Substring(0, 8));
            helper.IV = keyBytes;
            helper.Key = keyBytes;
            MemoryStream ms = new MemoryStream();
            using (CryptoStream cs = new CryptoStream(ms, helper.CreateEncryptor(), CryptoStreamMode.Write)) {
                cs.Write(Encoding.Default.GetBytes(str), 0, Encoding.Default.GetBytes(str).Length);
                cs.FlushFinalBlock();
                cs.Close();
            }
            return BytesToHex(ms.ToArray());
        }
        /// <summary>
        /// DES 解密
        /// </summary>
        /// <param name="str">DES 加密字符串</param>
        /// <returns>解密后的字符串</returns>
        public static string DESDecrypt(string str) {
            return DESDecrypt(str, "Match_Zhou_2009_02_11");
        }
        /// <summary>
        /// DES 解密
        /// </summary>
        /// <param name="str">DES 加密字符串</param>
        /// <param name="key">加密 key</param>
        /// <returns>解密后的字符串</returns>
        public static string DESDecrypt(string str, string key) {
            DES helper = DES.Create();
            byte[] hexToBytes = HexToByte(str);
            byte[] keyBytes = ASCIIEncoding.ASCII.GetBytes(MD5Hash(key).Substring(0, 8));
            helper.IV = keyBytes;
            helper.Key = keyBytes;
            MemoryStream ms = new MemoryStream();
            using (CryptoStream cs = new CryptoStream(ms, helper.CreateDecryptor(), CryptoStreamMode.Write)) {
                cs.Write(hexToBytes, 0, hexToBytes.Length);
                cs.FlushFinalBlock();
                cs.Close();
            }
            return Encoding.Default.GetString(ms.ToArray());
        }

    }
}
